﻿using AntMovement.Core;
using AntMovement.Core.Entity;
using AntMovement.Core.Enum;
using AntMovement.Core.IParameter;
using AntMovement.Core.Logic;
using AntMovement.Core.Logic.Base;
using AntMovement.Core.Model;
using AntMovement.Core.Tool;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AntMovement.Parameter
{
    public class IOParameter : InitFileBase, IIOParameter
    {
        public List<DI> DIDataSet { get; set; }
        public List<DO> DODataSet { get; set; }

        public ObservableCollection<AirCylinderModel> AirCylinderSource { get; set; }
        public ObservableCollection<SingleControlModel> SingleControlSource { get; set; }

        private IDialogHost _dialogHost;
        public IOParameter(IDialogHost dialogHost) : base("init", "ioparameter")
        {
            _dialogHost = dialogHost;
            if (System.IO.File.Exists(_path))
            {
                string str = base.Read();
                if (!string.IsNullOrEmpty(str))
                {
                    Dictionary<string, object> keyValues = System.Text.Json.JsonSerializer.Deserialize<Dictionary<string, object>>(str);
                    try
                    {
                        DIDataSet = System.Text.Json.JsonSerializer.Deserialize<List<DI>>(keyValues["DIDataSet"].ToString());
                        DODataSet = System.Text.Json.JsonSerializer.Deserialize<List<DO>>(keyValues["DODataSet"].ToString());
                        AirCylinderSource = System.Text.Json.JsonSerializer.Deserialize<ObservableCollection<AirCylinderModel>>(keyValues["AirCylinderSource"].ToString());
                        if (keyValues.ContainsKey("SingleControlSource"))
                        {
                            SingleControlSource = System.Text.Json.JsonSerializer.Deserialize<ObservableCollection<SingleControlModel>>(keyValues["SingleControlSource"].ToString());
                        }
                    }
                    catch (Exception)
                    {
                    }
                    try
                    {

                    }
                    catch (Exception)
                    {
                    }
                }
            }
            if (DIDataSet == null)
            {
                DIDataSet = new List<DI>();
            }
            if (DODataSet == null)
            {
                DODataSet = new List<DO>();
            }
            if (AirCylinderSource == null)
            {
                AirCylinderSource = new ObservableCollection<AirCylinderModel>();
            }
            if (SingleControlSource == null)
            {
                SingleControlSource = new ObservableCollection<SingleControlModel>();
            }
        }

        public bool Save()
        {
            Dictionary<string, object> data = new Dictionary<string, object>();
            data.Add("DIDataSet", DIDataSet);
            data.Add("DODataSet", DODataSet);
            data.Add("AirCylinderSource", AirCylinderSource);
            data.Add("SingleControlSource", SingleControlSource);
            return Save(System.Text.Json.JsonSerializer.Serialize(data, OptionsHelper.Options));
        }

        public ICoil GetCoil(string text)
        {
            try
            {
                DO dO = DODataSet.Where(x => x.Text == text).FirstOrDefault();
                if (dO != null) 
                {
                    switch (dO.Type)
                    {
                        case MotionType.PCI1230:
                            return new AntMovement.PCI1230.Logic.Coil(dO);
                        case MotionType.SolidTech_E_SerialCard:
                            return new AntMovernent.SolidTechESerialCard.Logic.Coil(dO);
                        case MotionType.PCI9016:
                            return new AntMovement.PCI9016.Logic.Coil(dO);
                        case MotionType.SMC308:
                            return new AntMovement.SDK.LTSMC.Logic.Coil(dO);
                        case MotionType.SMC304:
                            return new AntMovement.SDK.LTSMC.Logic.Coil(dO);
                    }
                }
            }
            catch (Exception)
            {
                _dialogHost?.DialogShow($"不存在输出变量 [{text}]!!!", LogLevel.Error, hostDialog: PopUpType.Global);
            }
            return null;
        }

        public NormalOpen GetNormalOpen(string text)
        {
            try
            {
                DI di = DIDataSet.Where(x => x.Text == text).FirstOrDefault();
                if (di != null) 
                {
                    return new NormalOpen(di);
                }
            }
            catch (Exception)
            {
                _dialogHost?.DialogShow($"不存在输出变量 [{text}]!!!", LogLevel.Error, hostDialog: PopUpType.Global);
            }
            return null;
        }

        public NormalClose GetNormalClose(string text)
        {
            try
            {
                DI di = DIDataSet.Where(x => x.Text == text).FirstOrDefault();
                if (di != null)
                {
                    return new NormalClose(di);
                }
            }
            catch (Exception)
            {
                _dialogHost?.DialogShow($"不存在输出变量 [{text}]!!!", LogLevel.Error, hostDialog: PopUpType.Global);
            }
            return null;
        }
        private List<IAirCylinder> _cylinders = new List<IAirCylinder>();

        public void InitAirCylinder(ILog log, IIOParameter io)
        {
            _cylinders.Clear();
            foreach (var item in AirCylinderSource)
            {
                _cylinders.Add(new AirCylinder(log, io, item));
            }
        }

        public IAirCylinder GetAirCylinder(string text) => _cylinders.FirstOrDefault(x => x.Name == text);

        public List<IAirCylinder> GetAirCylinderAll() => _cylinders;

        private List<ISingleControl> _singleControls = new List<ISingleControl>();

        public void InitSingleControl(IIOParameter io)
        {
            _singleControls.Clear();
            foreach (var item in SingleControlSource)
            {
                _singleControls.Add(new SingleControl(io, item));
            }
        }

        public ISingleControl GetSingleControl(string text, string type)
        {
            var domain = _singleControls.FirstOrDefault(x => x.Name == text && x.Type == type);
            if (domain == null)
            {
                throw new Exception($"未找到 [{text}] {type} 对象");
            }
            return domain;
        }

        public List<ISingleControl> GetSingleControlAll() => _singleControls;

    }
}
